grammar TableConfiguration;

@parser::header {package es.ise.core.mbg.parsing;

import org.mybatis.generator.config.*;
import org.apache.commons.lang.*;
}
@lexer::header {package es.ise.core.mbg.parsing;}

@members {
private Context context;

public TableConfigurationParser(TokenStream input, Context context) {
	this(input);
	this.context = context;
}
}

configuration
	:	config+
	;
	
config	:	(TABLE|VIEW) schema? table=ID REPLACE property=ID
		{
			TableConfiguration config = new TableConfiguration(context);
			if($schema.value != null)
				config.setSchema($schema.value);
			config.setTableName($table.text);
			config.setDomainObjectName($property.text);
		}
		{List<String> reprs = new ArrayList<String>();}
		(repr=representation {reprs.add($repr.value);})*
		{if(reprs.size() > 0) config.addProperty("representations", StringUtils.join(reprs, "#"));}
		(o=column {config.addColumnOverride($o.value);})*
		{context.addTableConfiguration(config);}
	;
	
schema returns [String value]
	: name=ID '.' {$value = $name.text;}
	;
	
representation returns [String value]
@init {
List<String> assocs = new ArrayList<String>();
}
	:	REPRESENT interfaze=ID (assoc=association {assocs.add($assoc.value);})*
		{$value = $interfaze.text + "?" + StringUtils.join(assocs, "&");}
	;

association returns [String value]
	:	WITH spec=ID '=' impl=ID
		{$value = $spec.text + "=" + $impl.text;}
	;
	
column returns [ColumnOverride value]
	:	COLUMN name=ID
		{$value = new ColumnOverride($name.text);}
		('%' jdbc=type {$value.setJdbcType($jdbc.value);})?
		(
			REPLACE
			(
				property=ID
				{
					$value.setJavaProperty($property.text);
					$value.addProperty("renamed", "yes");
				}
			)?
			(
				'%' java=type
				{
					$value.setJavaType($java.value);
				}
			)?
		)?
		(
			check[$value]
		)*
	;
	
type returns [String value]
	:	simple=ID {$value = $simple.text;}
	|	first=ID '.' last=type {$value = $first.text + "." + $last.value;}
	;
	
check[ColumnOverride param]
	// check de longitud
	: CHECK 'longitud' 'entre' INT 'y' INT
	| CHECK 'valores'
	  ID REPLACE STRING
	  {$param.addProperty("enumerated","M(\"Masculino\")");}
	;
	
TABLE	:	'tabla';
VIEW	:	'vista';
COLUMN	:	'columna';
CHECK	:	'check';
REPLACE	:	'->';
REPRESENT:	'representa';
WITH	:	'con';

ID	:	('a'..'z'|'A'..'Z')('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;
INT	:	'0'..'9'+;
WS	:	(' '|'\t'|'\n'|'\r')+ {$channel=HIDDEN;};
STRING
    :  '\'' ( ESC_SEQ | ~('\\'|'\'') )* '\''
    ;
    
COMMENT
    :   '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
    |   '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
    ;

fragment
NEWLINE	:	'\r'? '\n';	

fragment
HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;

fragment
ESC_SEQ
    :   '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
    |   UNICODE_ESC
    |   OCTAL_ESC
    ;

fragment
OCTAL_ESC
    :   '\\' ('0'..'3') ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7')
    ;

fragment
UNICODE_ESC
    :   '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
    ;
